package com.spring.controller.web;


import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.bind.ServletRequestUtils;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.multiaction.MultiActionController;

import com.spring.controller.util.UploadUtil;
import com.spring.domain.File;
import com.spring.service.file.IFile;

public class FileController extends MultiActionController{
	 
	private static final String FILE_LIST_VIEW 			= "file/fileList";
	private static final String FILE_INDEX_VIEW 		= "file/index";
	private static final String FILE_MODIFY_VIEW 		= "file/modify";
	
	private static final String FILE_UPLOAD_VIEW 		= "file/fileUpload";
	private static final String FILE_AJAX_UPLOAD_VIEW 	= "file/fileUpload/index";

	private final String ACTION_DELETE_FILE				=	"deleteFile";
    private final String ACTION_MODIFY					=	"modify";
	
	
	private IFile	fileService;
	
	private  String uploadPath = null;
	private  String maxBytes = null;
	
	/**
	 * Upload Ritorna un jSon come response.
	 * **/
	public ModelAndView upload(HttpServletRequest request, HttpServletResponse response)
	            throws ServletException, IOException {
	        
	        response.setContentType("text/plain");
	        PrintWriter out = response.getWriter();
	        out.print(UploadUtil.uploadFileFrom(request, maxBytes, uploadPath, fileService));
	        out.close();
	        
	        return null;
	 }

	public ModelAndView fileListPage(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
		
		 Map<String,Object> model = new HashMap<String, Object>();        
	     model.put("files", fileService.getFiles());
	     return new ModelAndView(FILE_LIST_VIEW,"model",model);
    }
	
	public ModelAndView fileModifyPage(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
		
		com.spring.domain.File toModify = fileService.getFileById(ServletRequestUtils.getIntParameter(request, "fileId", 0));
		Map<String,Object> model = new HashMap<String, Object>();        
	    model.put("file", toModify);
	    return new ModelAndView(FILE_MODIFY_VIEW,"model",model);
    }
	
	//ACTION PER GESTIRE OPERAZIONI SUL FILE
    public ModelAndView manageFile(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
    	
    	List<String> 	messages 		= new ArrayList<String>();
    	List<HashMap> 	errorMessages 	= new ArrayList<HashMap>();
        
    	List<String> 	idSelected 		= Arrays.asList (ServletRequestUtils.getStringParameters(request, "fileId") );
    	String 			action 			= ServletRequestUtils.getStringParameter	(request, "action"		,"0");
        int 			maxNumberImg 	= ServletRequestUtils.getIntParameter		(request, "maxNumberImg"	,0);
        
        String view = FILE_MODIFY_VIEW;
        Map<String,Object> model = new HashMap<String, Object>(); 
        
        logger.debug("action recuperata:"+action);
        
        if(ACTION_DELETE_FILE.equalsIgnoreCase(action)){
        	
        	List<File> files = getFileList(request);
        	
        	if(!files.isEmpty()){
        		logger.debug("files to delete:"+ files.toString());
        		
        		logger.debug("deleting files relations from DB:"+ files.toString());
				this.fileService.delete(files);
				
				
				logger.debug("deleting files from HD :"+ files.toString());
				final List<File> errorDeletionFromHD = UploadUtil.deleteFiles(files,uploadPath);
				
				if(errorDeletionFromHD.isEmpty()){
					messages.add("file.successDeleteHD");
					logger.debug("files deleted successfull from HD");
				}else{
					logger.debug("ERROR DELETING FILE");
					
					errorMessages.add(new HashMap<String,String>(){
	    				private static final long serialVersionUID = 1L;
	    				{
	    					put("key","file.errorDeleteHD");
	    					put("param1",errorDeletionFromHD.toString());
	    				}
	    			});
				}
				
			}else{
				logger.error("Empty contentId or no user selected");
				messages.add("error.parametroMancante");
				view = FILE_MODIFY_VIEW;
			}
        	
        	view = FILE_LIST_VIEW;
        	model.put("files", fileService.getFiles());
        	
        }else if(ACTION_MODIFY.equalsIgnoreCase(action)){
        	logger.debug("ACTION_MODIFY");
        	File toSave = getNewFileFrom(request);
        	model.put("file", toSave);
        	if(toSave.getId()!=0){
				this.fileService.update(toSave);
				messages.add("content.updatePositionForImgRelatedSucess");
        	}else{
				logger.error("Empty ID");
				messages.add("error.parametroMancante");
			}
        }

        model.put("messages"	, messages);
        model.put("errors"		, errorMessages);
        
        logger.info("Returning "+view+" view");
        return new ModelAndView(view, "model", model);
    }
    
    private File getNewFileFrom(HttpServletRequest req){
		
    	final String   	id				= ServletRequestUtils.getStringParameter(req, "id"			,"0");
    	final String 	descrizione		= ServletRequestUtils.getStringParameter(req, "description"	,"");
    	final String 	name			= ServletRequestUtils.getStringParameter(req, "name"		,"");
    	final String 	type			= ServletRequestUtils.getStringParameter(req, "type"		,"");
    	
    	return new File(){{
    		setId(Integer.valueOf(id));
    		setName(name);
    		setDescription(descrizione);
    		setType(type);
    	}};
    }
	
	private List<File> getFileList(HttpServletRequest request) {
		List<String> userIds = request.getParameterValues("fileId") == null ? Collections.<String>emptyList(): Arrays.asList(request.getParameterValues("fileId")) ;
		List<File> files = new ArrayList<File>();
		for (Iterator<String> iterator = userIds.iterator(); iterator.hasNext();) {
			final String 	id 		= iterator.next();
			final int 		intId 	= Integer.valueOf(id).intValue();
			final File 		file 	= fileService.getFileById(intId);
			
			
			files.add(new com.spring.domain.File(){{
				setId(intId);
				setName(file.getName());
				setDescription(file.getDescription());
				setType(file.getType());
			}}
				
			);
		}
		
		return files;
	}


	 /**
     * 	REDIREZIONI A JSP
     * */
    public ModelAndView index(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        return new ModelAndView(FILE_INDEX_VIEW);
    }
	
    public ModelAndView uploadFilePage(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
    	return new ModelAndView(FILE_AJAX_UPLOAD_VIEW);
    }
    
    public ModelAndView modifyFilePage(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
    	File toSave = getFileList(request).get(0);
    	Map<String,Object> model = new HashMap<String, Object>(); 
    	model.put("file", toSave);
    	return new ModelAndView(FILE_MODIFY_VIEW,"model",model);
    }
    
	public String getUploadPath() {
		return uploadPath;
	}

	public void setUploadPath(String uploadPath) {
		this.uploadPath = uploadPath;
	}

	public IFile getFileService() {
		return fileService;
	}

	public void setFileService(IFile fileService) {
		this.fileService = fileService;
	}

	public String getMaxBytes() {
		return maxBytes;
	}

	public void setMaxBytes(String maxBytes) {
		this.maxBytes = maxBytes;
	}
}
